/**
 * @Company 航天科技山西公司
 * @Project jd-1.0v
 * @Package com.jd.util.api
 * @Title FTPUtil.java
 * @Description TODO(描述)
 * @author 张鸿
 * @create 2016年5月20日-下午5:40:49
 * @version V 1.0
 */
package com.casic.common.utils;


import com.casic.modules.sys.entity.SysEnclosureEntity;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Company 航天科技山西公司
 * @Project jd-1.0v
 * @Package com.jd.util.api
 * @ClassName FTPUtil.java
 * @Description TODO(描述)
 * @author 颜金星
 * @create 2016年5月20日-下午5:40:49
 */
public class UploadFileUtil {

	// 本地异常日志记录对象
	private static final Logger logger = LoggerFactory
			.getLogger(UploadFileUtil.class);
	private static String ftpServerIP;
	private static int ftpServerPort;
	private static String  ftpUserName;
	private static String  ftpPassword;

	@Value("${ftp.iisaddress}")
	private  String iisServerIP;
	@Value("${ftp.iisport}")
	private  String iisServerPort;
	/**
	 * 上传文件临时目录
	 */
	private static final String uploadFileDir ="/upload/";

	@Autowired
	private FTPClientPool ftpClientPool;
    /**
     * 注意： 文件名不能用中文！
     * 		文件夹名称以正斜杠结尾！
     * 		如果文件夹不存在会自动创建！
     * @Title saveinFTP
     * @Description (描述)
     * @author 颜金星
     * @create 2016年5月23日-上午9:41:35
     * @Param @param FolderName
     * @Param @param FileName
     * @Param @param data
     * @Param @return
     * @return boolean
     * @throws
     */
	public synchronized static  void uploadFileFTP(String FolderName, String fileName, byte[] data){
		FTPClient ftpClient = new FTPClient();
		ByteArrayInputStream bis = null;
		try {
			if (StringUtils.isEmpty(FolderName)&&StringUtils.isEmpty(fileName)){
				ftpClient.connect(ftpServerIP,ftpServerPort);
				if(ftpClient.login(ftpUserName, ftpPassword)){
                    String[] a = FolderName.split("/");
					for (int i = 0; i < a.length; i++) {
						if (StringUtils.isEmpty(a[i])&&!ftpClient.changeWorkingDirectory(a[i])) {
							ftpClient.makeDirectory(a[i]);
							ftpClient.changeWorkingDirectory(a[i]);
						}
					}
					bis = new ByteArrayInputStream(data);
					ftpClient.setBufferSize(1024);
                    ftpClient.setDataTimeout(20000);
                    ftpClient.enterLocalPassiveMode();
                    // 设置文件类型(二进制类型)  
                    if (ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE)) {  
                    	 ftpClient.storeFile(fileName, bis);
                    }
                    bis.close();
				}else{
					logger.debug("FTP登陆失败！！");
				}
			}
		} catch (SocketException e) {
			logger.debug("FTP服务连接中断！！");
			e.printStackTrace();
		} catch (IOException e) {
			logger.debug("IOException！！");
			e.printStackTrace();
		}finally {  
            try {  
                // 关闭连接  
                ftpClient.disconnect();  
            } catch (IOException e) {
				logger.debug("FTP客户端关闭错误！！");
                e.printStackTrace();  
            }  
        }
	}
     
     /**
      * 
      * @Title downloadFile
      * @Description (FTP下载文件)
      * @author 颜金星
      * @create 2016年7月20日-下午12:45:42
      * @Param @param filePath（文件的路径）
      * @Param @return
      * @return boolean
      * @throws
      */
     public static InputStream downloadFile(String filePath){
    	 InputStream result = null ;
 		 FTPClient ftpClient = new FTPClient();
 		 try {
 			 //判断下载的路径不为空
 			if(!StringUtils.isEmpty(filePath)){
 				return result;
 			}
 			
 			String str[]=filePath.split("/");
 			String fileName=str[str.length-1];
 			String remoteFile="";
 			for(int i=0;i<str.length-1;i++){
 				remoteFile+=str[i]+"/";
 			}
 			ftpClient.connect(ftpServerIP,ftpServerPort);
			if(ftpClient.login(ftpUserName, ftpPassword)){
				ftpClient.setBufferSize(1024);
                ftpClient.setDataTimeout(18000);
                ftpClient.enterLocalPassiveMode();
                ftpClient.changeWorkingDirectory(remoteFile);
                result=ftpClient.retrieveFileStream(fileName);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {  
            try {  
                // 关闭连接  
                ftpClient.disconnect();  
            } catch (IOException e) { 
            	System.out.println("IOExceptionEND");
                e.printStackTrace();  
            }  
        }  
    	 return result;
     }

	/**
	 *  上传文件到本地
	 * @param file
	 * @return
	 */
	public static SysEnclosureEntity  uploadFile(MultipartFile file,String systemPath) throws IOException {
		SysEnclosureEntity sysEnclosureEntity=new SysEnclosureEntity();
		String oldFileName=file.getOriginalFilename();
		sysEnclosureEntity.setFileName(oldFileName);
		String fileType=oldFileName.substring(oldFileName.lastIndexOf(".")+1);
		sysEnclosureEntity.setFileSuffix(fileType);
		sysEnclosureEntity.setUploadDate(new Date());
		String filePath=getFolderName();
		String newFileName=getFileName(fileType);
		File dest = new File(systemPath +filePath);
		dest.setWritable(true,false);
		//判断文件夹是否存在
		if (!dest.exists() && !dest.isDirectory()) {
			//创建目录
			dest.mkdirs();
		}
		logger.debug("存放位置："+systemPath +filePath+newFileName);
		File newFile=new File(systemPath +filePath+newFileName);
		newFile.setWritable(true,false);
		BufferedOutputStream out = new BufferedOutputStream(
				new FileOutputStream(newFile));
		//写文件
		out.write(file.getBytes());
		out.flush();
		out.close();
		sysEnclosureEntity.setFilePath(filePath+newFileName);
		return sysEnclosureEntity;
	 }

	/**
	 * api上传文件(本地存放)
	 * @param files
	 * @return
	 */
	public static List<SysEnclosureEntity> apiUploadFile(List<MultipartFile> files,String systemPath) throws IOException {
		List<SysEnclosureEntity>  sysEnclosureEntityList=new ArrayList<>();
		SysEnclosureEntity sysEnclosureEntity=null;
		for(int i=0;i<files.size();i++){
			MultipartFile file=files.get(i);
			sysEnclosureEntity=new SysEnclosureEntity();
			String oldFileName=files.get(i).getOriginalFilename();
			sysEnclosureEntity.setFileName(oldFileName);
			String fileType=oldFileName.substring(oldFileName.lastIndexOf(".")+1);
			sysEnclosureEntity.setFileSuffix(fileType);
			sysEnclosureEntity.setUploadDate(new Date());
			//文件大小
//			double fileSize=fileItem.getSize()/1024.00;
			String filePath=getFolderName();
			String newFileName=getFileName(fileType);
			File dest = new File(systemPath +filePath);
			dest.setWritable(true,false);
			//判断文件夹是否存在
			if (!dest.exists() && !dest.isDirectory()) {
				//创建目录
				dest.mkdirs();
			}
			logger.debug("存放位置："+systemPath +filePath+newFileName);
			File newFile=new File(systemPath +filePath+newFileName);
			newFile.setWritable(true,false);
			BufferedOutputStream out = new BufferedOutputStream(
					new FileOutputStream(newFile));
			//写文件
			out.write(file.getBytes());
			out.flush();
			out.close();
			sysEnclosureEntity.setFilePath(filePath+newFileName);
			sysEnclosureEntityList.add(sysEnclosureEntity);
		}
		return sysEnclosureEntityList;
	}

	/**
	 * 获取文件名称
	 * @param fileType
	 * @return
	 */
	public static  String  getFileName(String  fileType){
     	return UUID.randomUUID().toString().replaceAll("\\-", "")+"."+fileType;
	 }

	/**
	 * 获取文件存放路径
	 * @return
	 */
	public static  String  getFolderName(){
		Calendar now = Calendar.getInstance();
		return "/security/"+now.get(Calendar.YEAR)+"/"+(now.get(Calendar.MONTH) + 1) +"/"+now.get(Calendar.DAY_OF_MONTH)+"/";
	}

	/** 上传文件处理(支持批量) */
	public static List<String> uploadImage(HttpServletRequest request) {
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
				request.getSession().getServletContext());
		List<String> fileNames = new ArrayList<>();
		String requestPath = "";
		if (multipartResolver.isMultipart(request)) {
			MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
			Iterator<String> iterator = multiRequest.getFileNames();
			SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
			String datePath = format.format(new Date());
			String pathDir = request.getSession().getServletContext().getRealPath(uploadFileDir) + datePath;
			requestPath = uploadFileDir + datePath;
			File dirFile = new File(pathDir);
			if (!dirFile.isDirectory()) {
				dirFile.mkdirs();
			}
			while (iterator.hasNext()) {
				String key = iterator.next();
				MultipartFile multipartFile = multiRequest.getFile(key);
				if (multipartFile != null) {
					String name = multipartFile.getOriginalFilename();

					if (name.indexOf(".") == -1 && "blob".equals(name)) {
						name = name + ".png";
					}
					String uuid = UUID.randomUUID().toString().replaceAll("\\-", "");
					String postFix = name.substring(name.lastIndexOf(".")).toLowerCase();
					String fileName = uuid + postFix;
					requestPath += fileName;
					String filePath = pathDir + File.separator + fileName;
					File file = new File(filePath);
					file.setWritable(true, false);
					try {
						multipartFile.transferTo(file);
						fileNames.add(filePath);
					} catch (Exception e) {
						logger.error(name + "保存失败", e);
					}
				}
			}
		}
		return fileNames;
	}

	public String uploadFileFTP(String filePath){
		FTPClient ftpClient = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String parentFolder = sdf.format(new Date());
		String separator = filePath.contains("/") ? "/" : "\\\\";
		String[] fileInfo = filePath.split(separator);
		String fileName = fileInfo[fileInfo.length - 1];
		InputStream inputStream = null;
		// 上传结果
		boolean result = false;
		// 重试计数
		int count = 0;

		do{
			try {
				inputStream = new FileInputStream(filePath);
				ftpClient = ftpClientPool.borrowObject();
				// 切换至根目录
				ftpClient.changeWorkingDirectory("/");

				if(ftpClient.changeWorkingDirectory(new String(parentFolder.getBytes(),
						"ISO-8859-1"))) {
					result = ftpClient.storeFile(fileName, inputStream);
				} else {
					// 如果当天的 FTP 目录不存在，则创建
					if(ftpClient.makeDirectory(new String(parentFolder.getBytes(),
							"ISO-8859-1"))) {
						// 切换至新创建的日期目录，并保存文件
						ftpClient.changeWorkingDirectory(new String(parentFolder.getBytes(),
								"ISO-8859-1"));
						result = ftpClient.storeFile(fileName, inputStream);
					} else {
						return "error";
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				// 上传失败后从连接池中销毁此客户端
				try {
					ftpClientPool.getFtpClientFactory().destroyObject(ftpClient);
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			} finally {
				if(inputStream != null) {
					try {
						inputStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				try {
					ftpClientPool.returnObject(ftpClient);
				} catch (Exception e) {
					e.printStackTrace();
				}
				// 如果上传失败，休眠一秒并重试
				if(!result) {
					count++;
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					logger.info("图片上传失败，开始第" + count + "重试" );
				}
			}
		} while(!result && count <= 3);
		return parentFolder + Constant.SEPARATOR + fileName;
	}

	public  String getImagePath(String url){
		return Constant.PROTOCOL + iisServerIP + Constant.PORTSEPARATOR + iisServerPort + Constant.SEPARATOR + url ;
	}
}
